package com.example.bbs.provider;


import com.alibaba.fastjson.JSONObject;
import com.example.bbs.domain.model.GiteeUser;
import com.example.bbs.service.impl.UserServiceImpl;
import com.example.bbs.util.HostHold;
import com.example.bbs.util.JwtTokenUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.Map;

/**
 * 封装Gitee登录的相关方法，一般先通过Post请求拿到token,再通过Get请求携带token获取用户信息
 * Post请求：把参数存在请求体中，一般有clienId, clientSecret,回调地址，code
 * Get请求：通过token拿到用户信息
 */
@Component
public class GiteeService {


    @Value("${gitee.client.id}")
    private String clientId;

    @Value("${gitee.client.secret}")
    private String clientSecret;

    @Value("${gitee.redirect.uri}")
    private String redirectUri;

    @Value("${gitee.token.url}")
    private String tokenUrl;

    @Value("${gitee.user.url}")
    private String userUrl;

    @Value("${context.path}")
    private String contextPath;

    @Value("${jwt.expiration}")
    private int expiration;

    @Value("${jwt.tokenHeader}")
    private String tokenHeader;

    @Autowired
    private JwtTokenUtil jwtTokenUtil;

    @Value("${jwt.tokenHead}")
    private String tokenHead;

    @Autowired
    private UserServiceImpl userService;

    @Resource
    private RedisTemplate userBasicInfoRedisTemplate;


    //发送Post请求，获取gitee登录的token
    private String getToken(String code, String clientId, String clientSecret, String redirectUri, String tokenUrl) {

        Map<String, Object> body = new HashMap<>();
        body.put("code", code);
        body.put("client_id", clientId);
        body.put("redirect_uri", redirectUri);
        body.put("client_secret", clientSecret);

        RestTemplate restTemplate = new RestTemplate();

        HttpEntity<Map<String, Object>> requestEntity = new HttpEntity<>(body);
        ResponseEntity<String> response = restTemplate.exchange(tokenUrl, HttpMethod.POST,
                requestEntity, String.class);
        JSONObject jsonObject = JSONObject.parseObject(response.getBody());
        String token = (String) jsonObject.get("access_token");
        return token;
    }

    //发送Get请求，用token获取用户信息
    private GiteeUser getUser(String token, String userUrl) {
        RestTemplate restTemplate = new RestTemplate();
        String url = userUrl + token;
        GiteeUser user = restTemplate.getForObject(url, GiteeUser.class);
        return user;
    }


    public void login(String code, HttpServletResponse response) {
        //发送Post请求拿到token
        String token = getToken(code, clientId, clientSecret, redirectUri, tokenUrl);
        //发送Get请求拿到user
        GiteeUser giteeUser = getUser(token, userUrl);
        if (giteeUser != null) {  //获取信息成功，签放cookie
            userService.save(giteeUser);
            //创建JWT
            String jwtToken = tokenHead + "-" + jwtTokenUtil.generateToken(String.valueOf(giteeUser.getId()));
            Cookie cookie = new Cookie(tokenHeader, jwtToken);
            cookie.setPath(contextPath);
            cookie.setMaxAge(expiration);
            response.addCookie(cookie);
        }
    }

    /**
     * 退出登录
     * @param request
     * @param response
     */
    public void logout(HttpServletRequest request, HttpServletResponse response) {
        //删除浏览器Cookie
        Cookie[] cookies = request.getCookies();
        if (cookies != null) {
            for (Cookie cookie : cookies) {
                if (cookie.getName().equals(tokenHeader)) {
                    cookie.setMaxAge(0);
                    response.addCookie(cookie);
                    break;
                }
            }
        }
        userBasicInfoRedisTemplate.delete(HostHold.get().getUserId());
    }
}
